home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / terms / tipx / fixedacu / telebit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-11  |  8.2 KB  |  382 lines

  1. /*
  2.  * Dialer support for Telebit Trailblazer Plus modem.
  3.  */
  4. /*+:EDITS:*/
  5. /*:08-09-1990-00:20-wht@n4hgf-fix result recognition - add instr() */
  6.  
  7. #ifndef lint
  8. static char *RCSid =
  9. "$Header: telebit.c,v 1.13.wht-1 90/08/29 rayan Exp $";
  10. #endif
  11.  
  12. #undef DEBUG 1
  13.  
  14. #ifdef    DEBUG
  15. int debug = 1;
  16. #define STATIC
  17. #else
  18. #define STATIC static
  19. #endif
  20.  
  21. #include "tip.h"
  22. #include <sys/time.h>
  23.  
  24. /*
  25.  * The following is the Telebit register setup used here with this code, with
  26.  * the TB+ attached to a fixed-speed interface on a remote terminal server.
  27.  * When attaching to a computer the appropriate register should be set so
  28.  * the TB+ interface speed matches the connect baud rate.
  29.  *
  30. E0 F1 M1 Q1 P V1 X1     Version BA4.00
  31. S00=001 S01=000 S02=043 S03=013 S04=010 S05=008 S06=002 S07=040 S08=002 S09=006
  32. S10=007 S11=070 S12=050 
  33. S45=255 S47=004 S48=000 S49=000
  34. S50=000 S51=005 S52=002 S53=004 S54=003 S55=000 S56=017 S57=019 S58=000 S59=000
  35. S60=000 S61=000 S62=003 S63=001 S64=000 S65=000 S66=000 S67=000 S68=255 
  36. S90=000 S91=000 S92=000 S95=000 
  37. S100=000 S101=000 S102=000 S104=000 
  38. S110=001 S111=030 S112=001 
  39. S121=000 
  40.  *
  41.  */
  42.  
  43.     /* commands */
  44. STATIC char    NAME[] =        "telebit";
  45. STATIC char    WARMUP[] =        "\rat\r";
  46. STATIC char    RESULT_CODES[] =    "\ratq0\r";
  47. STATIC char    DONT_ANSWER[] =        "\rats0=0\r";
  48. STATIC char    IGN_ESCAPE[] =        "\rats55=3\r";
  49. STATIC char    CODES_4[] =        "\ratx1\r";
  50. STATIC char    DIAL_PREFIX[] =        "\ratdt";
  51.  
  52.     /* result codes */;
  53. STATIC char    MDM_OK[] =        "OK";
  54. STATIC char    RING[] =        "RING";
  55. STATIC char    RRING[] =        "RRING";
  56. STATIC char    NO_CARRIER[] =        "NO CARRIER";
  57. STATIC char    ERROR[] =        "ERROR";
  58. STATIC char    CONNECT[] =        "CONNECT 300";
  59. STATIC char    CONNECT_1200[] =    "CONNECT 1200";
  60. STATIC char    CONNECT_2400[] =    "CONNECT 2400";
  61. STATIC char    CONNECT_FAST[] =    "CONNECT FAST";
  62. STATIC char    NO_DIALTONE[] =        "NO DIALTONE";
  63. STATIC char    NO_ANSWER[] =        "NO ANSWER";
  64. STATIC char    BUSY[] =        "BUSY";
  65.  
  66. STATIC char    *notbcon[] =    {    BUSY,
  67.                     NO_DIALTONE,
  68.                     NO_ANSWER,
  69.                     ERROR,
  70.                     RING,
  71.                     NO_CARRIER,
  72.                     0
  73.                 };
  74.  
  75. /* The baudrate starts at 300, and doubles for next element of array */
  76. STATIC char    *tbcon[] =    {    CONNECT,
  77.                     "ignore",
  78.                     CONNECT_1200,
  79.                     CONNECT_2400,
  80.                     "ignore",
  81.                     "ignore",
  82.                     CONNECT_FAST,
  83.                     0
  84.                 };
  85. #ifdef    USG
  86. STATIC struct termio termio;        /* needed on USG to set HUPCL */
  87. #endif    /* USG */
  88.  
  89. #define    CMD_DELAY    5    /* number of seconds to wait for response
  90.                     while in command mode */
  91. #define DIAL_DELAY    120    /* number of seconds to wait for response
  92.                     after sending dial string */
  93. #define    MAXSTR    100
  94.  
  95. static jmp_buf    jmpbuf;
  96.  
  97. int     tbread(), tbwrite();
  98.  
  99. /*+-------------------------------------------------------------------------
  100.     instr(s1,s2)
  101.  
  102.   find s2 in s1; returns 0 if found, 1 if not found
  103. --------------------------------------------------------------------------*/
  104. instr(s1,s2)
  105. register char *s1;
  106. char *s2;
  107. {
  108.     register len = strlen(s2);
  109.     while(s1 = strchr(s1,*s2))
  110.     {
  111.         if(!strncmp(s2,s1,len))
  112.             return(0);
  113.         s1++;
  114.     }
  115.     return(1);
  116. }    /* end of instr */
  117.  
  118. tb_dialer(num, acu)
  119. register char    *num;
  120. char    *acu;
  121. {
  122.     int    ret;
  123.     int    i, j;
  124.     char    buf1[MAXSTR], buf2[MAXSTR], buf3[MAXSTR];
  125. #ifdef ACULOG
  126.     char    line[MAXSTR];
  127. #endif
  128.  
  129.     /*
  130.      * wake up the modem if it's listening...
  131.      */
  132.     if (boolean(value(VERBOSE)))
  133.         printf("diddling dialer...");
  134. #ifdef DEBUG
  135.     if (debug)
  136.         fprintf(stderr, "BR=%d\n", BR);
  137. #endif
  138.  
  139.     sleep(1);    /* Give modem time to settle down after reset */
  140.     if ((!tbset(RESULT_CODES, buf1, num, "is naughty")
  141.              && !tbset(RESULT_CODES, buf1, num, "not listening"))
  142.         || !tbset(DONT_ANSWER, buf1, num, "auto-answer not turned off")
  143.         || !tbset(IGN_ESCAPE, buf1, num, "escape code not turned off")
  144.         || !tbset(CODES_4, buf1, num, "result codes not set"))
  145.         return 0;
  146.  
  147.     /* insurance ? */
  148. #ifdef    USG
  149.     if (ioctl(FD, TCGETA, &termio) < 0)
  150.         perror("tip: TCGETA ioctl");
  151.     termio.c_cflag |= HUPCL;
  152.     if (ioctl(FD, TCSETA, &termio) < 0)
  153.         perror("tip: TCSETA ioctl");
  154. #else    /* USG */
  155.     if (ioctl(FD, TIOCHPCL, 0) < 0)
  156.         perror("tip: TIOCHPCL ioctl");
  157. #endif    /* USG */
  158.  
  159.     buf2[0] = '\0';
  160.     for (i = 0, j = 300; tbcon[i] != (char *)0; i++, j*=2) {
  161.         if (BR == j) {
  162.             strcpy(buf2, tbcon[i]);
  163.             break;
  164.         }
  165.     }
  166.     if (buf2[0] == '\0') {
  167.         sprintf(buf2, "unsupported baud rate (%d)", BR);
  168.         goto error;
  169.     }
  170.  
  171.     /* Is it safe to just say ATD and let the options setting rule? */
  172.     tbwrite(DIAL_PREFIX);
  173.     tbwrite(num);
  174.     tbwrite("\r");
  175.     if (boolean(value(VERBOSE)))
  176.         printf(" dialing... ");
  177.     do {
  178.         if (ret = tbread(buf1, DIAL_DELAY, (u_int) strlen(buf2)) == 0) {
  179.             strcpy(buf2, "TIMEOUT on dial");
  180.             goto error;
  181.         }
  182.         if (ret == -1) {
  183.             strcpy(buf2, "ioctl failed");
  184.             goto error;
  185.         }
  186.     } while (instr(buf1, RRING) == 0
  187.         && (!boolean(value(VERBOSE)) || (printf("rrring... "), 1)));
  188.     if (instr(buf1, buf2) != 0) {
  189.         for (i = 0, j = 300; tbcon[i] != (char *)0; i++, j *= 2) {
  190.             if (!instr(buf1, tbcon[i])) {
  191.                 /* This should never fail */
  192.                 if ((i = speed(j)) != NULL) {
  193.                     BR = j;
  194.                     ttysetup(i);
  195.                 } else {
  196.                     printf("speed(%d) failed\n", j);
  197.                     return 0;
  198.                 }
  199.                 goto ok;
  200.             }
  201.         }
  202.         for (i = 0; notbcon[i] != (char *)0; i++) {
  203.             if (!instr(buf1, notbcon[i])){
  204.                 char    *bp, *cp;
  205.                 for (bp = buf2, cp = notbcon[i]; *cp; cp++) {
  206.                     if (*cp != '\r' && *cp != '\n')
  207.                         *bp++ = *cp;
  208.                 }
  209.                 *bp = '\0';
  210.                 goto error;
  211.             }
  212.         }
  213.         (void) strcpy(buf2, "UNKNOWN ERROR [");
  214.         (void) strcat(buf2, buf1);
  215.         (void) strcat(buf2, "]");
  216. error:
  217.         printf("dial failed (%s)\n", buf2);
  218.         sprintf(buf3, "dial failed (%s)", buf2);
  219. #ifdef ACULOG
  220.         logent(value(HOST), num, NAME, buf3);
  221. #endif
  222.         return 0;
  223.     }
  224. ok:
  225.     if (boolean(value(VERBOSE)))
  226.         printf("(%d baud) ", BR);
  227.     i = 2;
  228. #ifdef    USG
  229.     if (ioctl(FD, TCFLSH, i) < 0)
  230.         perror("tip: TCFLSH ioctl");
  231. #else    /* USG */
  232.     if (ioctl(FD, TIOCFLUSH, &i) < 0)
  233.         perror("tip: TIOCFLUSH ioctl");
  234. #endif    /* USG */
  235.     return 1;
  236. }
  237.  
  238.  
  239. tb_disconnect()
  240. {
  241. #ifdef    USG
  242.     if (ioctl(FD, TCGETA, &termio) < 0)
  243.         perror("tip: TCGETA ioctl");
  244.     termio.c_cflag &= (CBAUD & B0);
  245.     if (ioctl(FD, TCSETA, &termio) < 0)
  246.         perror("tip: TCSETA ioctl");
  247.     sleep(2);
  248. #endif    /* USG */
  249.     (void) close(FD);
  250. }
  251.  
  252.  
  253. tb_abort()
  254. {
  255.     tb_disconnect();
  256. }
  257.  
  258. STATIC
  259. tbwrite(cp)
  260. register char    *cp;
  261. {
  262.     struct timeval t;
  263.  
  264.     for (; *cp != '\0' ; cp++) {
  265.         if (write(FD, cp, 1) != 1) {
  266.             perror("tip: tbwrite: write error");
  267.             return;
  268.         }
  269. #ifdef    DEBUG
  270.         if (debug) {
  271.             fprintf(stderr, "written '%c'\n", *cp);
  272.         }
  273. #endif
  274.         t.tv_sec = 0;
  275.         t.tv_usec = (20 * 10 * 1000000)/BR;
  276.         (void) select(32, 0, 0, 0, &t);
  277.     }
  278. }
  279.  
  280. STATIC
  281. tbread(buf, timeout, max)
  282. register char    *buf;
  283. unsigned int timeout, max;
  284. {
  285.     int    alarmtr();
  286.     struct timeval t;
  287.     register char    *rp;
  288.     unsigned int numread, numprev = 0, numpndg = 0;
  289.     unsigned int toread;
  290.  
  291. #ifdef    DEBUG
  292.     if (debug)
  293.         fprintf(stderr, "\n---------\nentering tbread(): timeout is: %d, max is: %d\n", timeout, max);
  294. #endif
  295.     rp = buf;
  296.     *rp = '\0';
  297.     (void) signal(SIGALRM, alarmtr);
  298.     if (setjmp(jmpbuf)) {
  299.         *rp = '\0';
  300.         return 0;
  301.     }
  302.     (void) alarm(timeout);
  303.         /* wait till modem says something or until timeout */
  304.     while (numpndg == 0 || numpndg != numprev) {
  305.         numprev = numpndg;
  306.         if (ioctl(FD, FIONREAD, &numpndg) == -1) {
  307.             perror("tip: FIONREAD ioctl");
  308.             return -1;
  309.         }
  310.         t.tv_sec = 0;
  311.         t.tv_usec = (100 * 10 * 1000000)/BR;
  312.         (void) select(32, 0, 0, 0, &t);
  313.     }
  314.     (void) alarm(0);
  315. #ifdef    DEBUG
  316.     if (debug)
  317.         fprintf(stderr, "number of chars waiting is: %d\n", numpndg);
  318. #endif
  319.     toread = ((numpndg > max) ? max : numpndg);
  320.       if ((numread = read(FD, rp, toread)) < toread)
  321.         perror("read error");
  322. #ifdef    DEBUG
  323.     if (debug) {
  324.         int i; char *p;
  325.         fprintf(stderr, "read %d chars:", numread);
  326.         for (i=0, p=rp; i<numread; i++, p++)
  327.             fprintf(stderr, "%0.2x ", *p);
  328.         fprintf(stderr, "\n");
  329.         fflush(stderr);
  330.     }
  331. #endif
  332.     rp += numread;
  333.     *rp = '\0';
  334. #ifdef    DEBUG
  335.     if (debug) {
  336.         fprintf(stderr, "\nbuf contains: ->%s<-\n", buf);
  337.         fprintf(stderr, "leaving tbread()\n-----------\n");
  338.         fflush(stderr);
  339.     }
  340. #endif
  341.     return 1;
  342. }
  343.  
  344.  
  345. STATIC
  346. accept(baudrate)
  347. int    baudrate;
  348. {
  349.     int i;
  350.  
  351.     BR = baudrate;
  352.     if ((i = speed(baudrate)) != NULL)
  353.         ttysetup(i);
  354. }
  355.  
  356.  
  357. STATIC
  358. alarmtr()
  359. {
  360. #ifdef    DEBUG
  361.     if (debug)
  362.         fprintf(stderr, "alarm went off!\n");
  363. #endif
  364.     longjmp(jmpbuf, 1);
  365. }
  366.  
  367. STATIC int
  368. tbset(tosend, buf, num, errmsg)
  369. char    *tosend, *buf, *num, *errmsg;
  370. {
  371.     tbwrite(tosend);
  372.     tbread(buf, CMD_DELAY, (u_int) (sizeof MDM_OK) - 1);
  373.     if (instr(buf, MDM_OK,) != 0) {
  374.         printf(" %s modem %s\n", NAME, errmsg);
  375. #ifdef ACULOG
  376.         logent(value(HOST), num, NAME, errmsg);
  377. #endif
  378.         return 0;
  379.     }
  380.     return 1;
  381. }
  382.